package org.smart4j.framework.common.util;

import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * 反射工具类
 *
 * @author YooLin1c
 * @version 1.0.0
 * @since 2018-01-30 14:11
 */
@Slf4j
public final class ReflectionUtil {
    /**
     * 利用反射创建类的对象
     *
     * @param clazz 类
     * @param <T>   类的泛型
     * @return 类的对象
     */
    @SuppressWarnings("unchecked")
    public static <T> T newInstance(Class<?> clazz) {
        T instance;
        try {
            instance = (T) clazz.newInstance();
        } catch (Exception e) {
            log.error("new instance failed!", e);
            throw new RuntimeException(e);
        }
        return instance;
    }

    /**
     * 调用指定对象的方法
     *
     * @param obj    指定对象
     * @param method 方法
     * @param args   参数
     * @return 方法返回值
     */
    public static Object invokeMethod(Object obj, Method method, Object... args) {
        Object result;
        method.setAccessible(true);
        try {
            result = method.invoke(obj, args);
        } catch (Exception e) {
            log.error("invoke method ".concat(method.getName()).concat(" failed!"), e);
            throw new RuntimeException(e);
        }
        return result;
    }

    /**
     * 给指定对象的成员变量赋值
     *
     * @param obj   指定对象
     * @param field 成员变量
     * @param value 赋予的值
     */
    public static void setFiled(Object obj, Field field, Object value) {
        field.setAccessible(true);
        try {
            field.set(obj, value);
        } catch (IllegalAccessException e) {
            log.error("set field ".concat(field.getName()).concat(" with value : ").concat(String.valueOf(value)).concat(" failed!"), e);
            throw new RuntimeException(e);
        }
    }
}
